package com.taofuxn.admin.dao.opt;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.taofuxn.admin.common.util.CheckUtil;
import com.taofuxn.admin.common.util.CopyUtils;
import com.taofuxn.admin.dao.dto.ResourceDto;
import com.taofuxn.admin.dao.entity.*;
import com.taofuxn.admin.dao.repository.TbSysRoleResourceMapper;
import com.taofuxn.admin.dao.repository.TbSysUserMapper;
import com.taofuxn.admin.dao.repository.TbSysUserRoleMapper;
import com.taofuxn.admin.dao.repository.extend.TbSysResourceExtendMapper;
import com.taofuxn.admin.dao.repository.extend.TbSysRoleExtendMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceEditor;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author wong
 * @Date: 2020-11-27
 * @Version: 1.0
 */
@Repository
public class SysUserOpt {

    @Autowired
    private TbSysUserMapper tbSysUserMapper;
    @Autowired
    private TbSysResourceExtendMapper tbSysResourceMapper;
    @Autowired
    private TbSysRoleExtendMapper tbSysRoleMapper;
    @Autowired
    private TbSysRoleResourceMapper tbSysRoleResourceMapper;
    @Autowired
    private TbSysUserRoleMapper tbSysUserRoleMapper;

    public TbSysUser getUserByAmount(String loginName) {
        TbSysUserExample example = new TbSysUserExample();
        example.createCriteria().andLoginNameEqualTo(loginName).andIsDeletedEqualTo((byte) 0).andLockedEqualTo((byte) 0);
        List<TbSysUser> list = tbSysUserMapper.selectByExample(example);
        return CollectionUtils.isEmpty(list) ? null:list.get(0);
    }


    /**
     * 从根节点查询
     * @return
     */
    public List<ResourceDto> selectResourceList() {
        Map<String, Object> map = Maps.newHashMap();
        map.put("parentId", 0);
        map.put("type", null);
       List<ResourceDto> resourceDtos = tbSysResourceMapper.selectResourceList(map);
       return resourceDtos;
    }


    public void updateResource(TbSysResource resource) {
        tbSysResourceMapper.updateByPrimaryKeySelective(resource);
    }


    public void saveResource(TbSysResource resource) {
        if (!CheckUtil.checkIdForLong(resource.getParentId())) {
            resource.setLevel((short) 1);
            Integer sort = tbSysResourceMapper.selectMaxSort((long) 0);
            resource.setSort(sort == null ? 0 :sort.shortValue());
        } else {
            TbSysResource parent = getResourceById(resource.getParentId());
            resource.setLevel((short) (parent.getLevel() + 1));
            resource.setParentIds(parent.getParentIds());
            Integer sort = tbSysResourceMapper.selectMaxSort(parent.getParentId());
            resource.setSort(sort == null ? 0 : sort.shortValue());
        }
        tbSysResourceMapper.insertSelective(resource);
        resource.setParentIds(StringUtils.isBlank(resource.getParentIds()) ? resource.getId() + "," : resource.getParentIds() + resource.getId() + ",");
        tbSysResourceMapper.updateByPrimaryKeySelective(resource);
    }


    public TbSysResource getResourceById(Long parentId) {
        return tbSysResourceMapper.selectByPrimaryKey(parentId);
    }


    public void deleteResource(Long id) {
        List<TbSysResource> list = tbSysResourceMapper.selectAll();
        for (int i = 0; i < list.size(); i++) {
            TbSysResource resource = list.get(i);
            if (id.equals(resource.getParentId())) {
                deleteResource(resource.getId());
            }
        }
        tbSysResourceMapper.deleteByPrimaryKey(id);
    }


    public void saveUser(TbSysUser user) {
        user.setCreateBy("");
        user.setUpdateBy("");
        tbSysUserMapper.insertSelective(user);
    }


    public long countRole(TbSysRole param) {
        TbSysRoleExample example = new TbSysRoleExample();
        TbSysRoleExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(param.getName())){
            criteria.andNameLike("%"+param.getName()+"%");
        }
        if (!StringUtils.isEmpty(param.getCode())){
            criteria.andCodeEqualTo(param.getCode());
        }
        criteria.andIsDeletedEqualTo((byte) 0);

        return  tbSysRoleMapper.countByExample(example);
    }

    public List<TbSysRole> selectRoleByPage(int offset, int limit, TbSysRole param) {
        TbSysRoleExample example = new TbSysRoleExample();
        example.setLimit(limit);
        example.setOffset(offset);
        example.setOrderByClause("sort asc");
        TbSysRoleExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(param.getName())){
            criteria.andNameLike("%"+param.getName()+"%");
        }
        if (!StringUtils.isEmpty(param.getCode())){
            criteria.andCodeEqualTo(param.getCode());
        }
        criteria.andIsDeletedEqualTo((byte) 0);
        return tbSysRoleMapper.selectByExample(example);
    }

    public List<TbSysRoleResource> selectResourceByRole(List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)){
            return Lists.newArrayList();
        }
        return tbSysResourceMapper.selectResourceByRole(roleIds);
    }

    public long checkRepeaterRoleName(String name, Long roleId) {
        TbSysRoleExample example = new TbSysRoleExample();
        TbSysRoleExample.Criteria criteria = example.createCriteria();
        criteria.andNameEqualTo(name);
        if (roleId != null){
            criteria.andIdNotEqualTo(roleId);
        }
        criteria.andIsDeletedEqualTo((byte) 0);
        return tbSysRoleMapper.countByExample(example);
    }

    public void updateRole(TbSysRole tbSysRole) {
        tbSysRoleMapper.updateByPrimaryKeySelective(tbSysRole);
    }

    public long saveRole(TbSysRole tbSysRole) {
        if (tbSysRoleMapper.insertSelective(tbSysRole) >0){
            return tbSysRole.getId();
        }
        throw new RuntimeException("插入角色失败");
    }

    public void updateRoleResource(long roleId, List<Long> menuIds) {
        if (!CheckUtil.checkIdForLong(roleId)){
            return;
        }
        menuIds = menuIds.stream().distinct().collect(Collectors.toList());
        TbSysRoleResourceExample example = new TbSysRoleResourceExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        tbSysRoleResourceMapper.deleteByExample(example);
        if (!CollectionUtils.isEmpty(menuIds)){
            tbSysRoleResourceMapper.batInsertRoleResource(roleId,menuIds);
        }
    }

    public void deleteRoles(Long roleId) {
        tbSysRoleMapper.deleteByPrimaryKey(roleId);
        TbSysRoleResourceExample example = new TbSysRoleResourceExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        tbSysRoleResourceMapper.deleteByExample(example);
    }

    public long countUser(TbSysUser param) {
        TbSysUserExample example = new TbSysUserExample();
        TbSysUserExample.Criteria criteria = example.createCriteria();
        criteria.andIsDeletedEqualTo((byte) 0);
        if (null != param) {
            if (!StringUtils.isEmpty(param.getLoginName())) {
                criteria.andLoginNameLike("%" + param.getLoginName() + "%");
            }
            if (!StringUtils.isEmpty(param.getNickName())) {
                criteria.andNickNameEqualTo("%" + param.getNickName() + "%");
            }
            if (!StringUtils.isEmpty(param.getTel())) {
                criteria.andTelEqualTo(param.getTel());
            }
        }
        return tbSysUserMapper.countByExample(example);
    }

    public List<TbSysUser> selectUserBypage(int offset, int limit, TbSysUser param) {
        TbSysUserExample example = new TbSysUserExample();
        example.setOrderByClause("create_time desc");
        example.setLimit(limit);
        example.setOffset(offset);
        TbSysUserExample.Criteria criteria = example.createCriteria();
        criteria.andIsDeletedEqualTo((byte) 0);
        if (null != param) {
            if (!StringUtils.isEmpty(param.getLoginName())) {
                criteria.andLoginNameLike("%" + param.getLoginName() + "%");
            }
            if (!StringUtils.isEmpty(param.getNickName())) {
                criteria.andNickNameEqualTo("%" + param.getNickName() + "%");
            }
            if (!StringUtils.isEmpty(param.getTel())) {
                criteria.andTelEqualTo(param.getTel());
            }
        }
        return tbSysUserMapper.selectByExample(example);
    }

    public List<TbSysRole> getRoleByIds(List<Long> ids){
        TbSysRoleExample example = new TbSysRoleExample();
        example.createCriteria().andIdIn(ids).andIsDeletedEqualTo((byte) 0);
        return tbSysRoleMapper.selectByExample(example);
    }

    /**
     * 用户角色列表
     * @param userIds
     * @return
     */
    public Map<Long, List<TbSysRole>> getRolesByUserIds(List<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)){
            return null;
        }
        TbSysUserRoleExample example = new TbSysUserRoleExample();
        example.createCriteria().andUserIdIn(userIds);
        List<TbSysUserRole> userRoles = tbSysUserRoleMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(userRoles)){
            return null;
        }
        Map<Long,List<TbSysUserRole>> userRoleMap = userRoles.stream().collect(Collectors.groupingBy(TbSysUserRole::getUserId));
        Map<Long,TbSysRole> tbSysRoleMaps  = getRoleByIds(userRoles.stream().map(TbSysUserRole::getRoleId).distinct().collect(Collectors.toList()))
                .stream().collect(Collectors.toMap(TbSysRole::getId, Function.identity(),(o1,o2)->o1));
        Map<Long, List<TbSysRole>> rt = new HashMap<>();
        for (Long userId : userIds) {
            List<TbSysUserRole> myUserRoles = userRoleMap.get(userId);
            if (!CollectionUtils.isEmpty(myUserRoles)){
                rt.put(userId,myUserRoles.stream().map(c-> tbSysRoleMaps.get(c.getRoleId())).filter(Objects::nonNull).collect(Collectors.toList()));
            }
        }
        return rt;
    }

    public void updateUser(TbSysUser tbSysUser) {
        if (tbSysUser!=null && CheckUtil.checkIdForLong(tbSysUser.getId())){
            tbSysUserMapper.updateByPrimaryKeySelective(tbSysUser);
        }
    }

    public void deleteUserRoles(Long userId) {
        if (CheckUtil.checkIdForLong(userId)) {
            TbSysUserRoleExample example = new TbSysUserRoleExample();
            example.createCriteria().andUserIdEqualTo(userId);
            tbSysUserRoleMapper.deleteByExample(example);
        }
    }

    public void addUserRoles(Long userId, List<Long> roleIds) {
        if (!CollectionUtils.isEmpty(roleIds)){
            tbSysUserRoleMapper.batInsert(userId,roleIds);
        }
    }

    public TbSysUser getUserById(Long userId) {
        return tbSysUserMapper.selectByPrimaryKey(userId);
    }

    public List<TbSysResource> getResourceByIds(List<Long> resourceIds) {
        TbSysResourceExample example = new TbSysResourceExample();
        example.setOrderByClause("sort");
        example.createCriteria().andIdIn(resourceIds.stream().distinct().collect(Collectors.toList())).andIsDeletedEqualTo((byte) 0);
        return tbSysResourceMapper.selectByExample(example);
    }


}
